#pragma once
#ifndef SYPX_SPRITE
#define SYPX_SPRITE
#include "Base.h"
#include "Mesh.h"
#include "SpriteInstance.h"

namespace SypX
{	
	class SpriteInstance;
	///A sprite class represents a 2 dimensional mesh with a texture mapped onto it.
	///Sprite class supports animated sprites by mapping/switching parts of the texture onto the mesh.
	///Each mapping corresponds to a frame of the sprite animation. Sprite class also supports
	///actions which define the number and size of frames for that action. A Sprite can constitute of
	///multiple Actions which can each contain multiple frames of animation of which each frame has 
	///12 orientations. Sprite Textures only contain orientations of 6 O'Clock to 12 O'Clock(Clock orientation)
	///Orientations 1 O'Clock to 5 O'Clock are dynamically generated during drawtime by flipping the directly
	///opposite orientation.
	class SYPXAPI Sprite :	public Mesh
	{
	public:
		///SpriteActions structure which contains information for an action. Each action is a containment of
		///multiple frames of animation
		struct SpriteActions
		{
			///The Action's name
			String actionName;
			///Number of Frames in the action
			UShort numFrames;
			///The vertical point(in pixels) where the first frame begins.
			UShort btm;
			///The width of an individual frame.
			UShort cellWidth;
			///The height of an individual frame.
			UShort cellHeight;
			///The total action animation length in seconds
			float totalLength;
			///An array of 
			FloatArray frameDuration;

		};	
		///Default Constructor
		Sprite();
		///Deconstructor
		virtual ~Sprite(void);
		///Constructs a sprite from a .spr file generated by Caleb Tools?
		///The genColor argument describes whether the generated Sprite should support per-vertex coloring(requires more memory)
		///Note: Loading Sprites from .spr generates an internal dummy meshinstance to help with drawing buffered instances
		///To prevent this dummy meshinstance from influencing reference counting, the Sprite class internally decreases the Sprite and
		///it's texture's reference count. This will return the Resources ref count to their original counts.
		///This count is added back only prior to deleting the dummy MeshInstance
		///Any other usage of Sprite, either directly or via a derived class can either do the same if the 
		///Resource is to be cleaned up by the ResourceManager and the Sprite destructor will do the necessary
		///reference adding and deletion of the dummy MeshInstance.
		///Or if the Sprite is to be retained regardless of usage(ie. Fonts), you must delete the dummy MeshInstance
		///and set it to 0 to prevent the Sprite destructor from attempting to delete it again.
		static Sprite* loadSpriteFromFile(const String& filename, bool genColor = false);
		///Returns a pointer to the Sprite's texture
		Texture* getTexture();		
		///Updates mesh to reflect current Action/Angle/Frame of the SpriteInstance passed in
		void updateMesh(SpriteInstance* si);
		///Buffers the geometry for this instance but does not draw it immediately
		///This method is preferred and more efficient over rendering individual sprites 1 by 1
		void bufferInstance(SpriteInstance* si);
		///This method draws all buffered instances so far and clears the internal buffer
		void drawBufferedInstances();
		///Sets the Global Sprite angle offset to use for when rendering. (Useful for mobile devices which can be played in potrait/landscape)
		static void setOffsetAngle(int off);
	protected:		
		Texture* tex;			
		std::vector<SpriteActions> actions;
		friend class SpriteInstance;
		///Dummy MeshInstance to draw buffered instances at origin(Buffered instances are already xfmed/baked)
		MeshInstance* mi;
		///Global Sprite angle offset to use for when rendering. (Useful for mobile devices which can be played in potrait/landscape)
		static int offset;
	};
}
#endif